package com.framework.controller.minio;

import cn.dev33.satoken.util.SaResult;
import com.alibaba.fastjson.JSON;
import com.framework.entity.ChunkFile;
import com.framework.entity.MergeFile;
import com.framework.service.ChunkFileService;
import com.framework.service.MergeFileService;
import com.framework.service.MinioService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.json.JSONParser;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
import java.util.concurrent.ExecutionException;


/**
 * @Description: minio接口
 * @author: 姚佳飞
 * @createTime: 2023/12/10 15:38
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/minio/")
@Slf4j
public class MinioFileController {

    private final ChunkFileService chunkFileService;
    private final MergeFileService mergerFileService;
    private final MinioService minioService;

    /**
     * 接收分片文件上传请求
     *
     * @param file      上传的文件
     * @param chunkFile 文件上传信息
     * @return 上传结果
     */
    @PostMapping("upload")
    public synchronized SaResult uploadReturnUrl
    (@RequestParam("file") MultipartFile file,
     @RequestParam("chunkFile") String chunkFile)
            throws NoSuchAlgorithmException, IOException,
            ExecutionException, InterruptedException {
        long size = file.getSize();
        log.info("size:" + size);
        if (size > 20 *(1024.0 * 1024.0)) {
            return SaResult.error("文件大小超过20M");
        }
        ChunkFile chunk = JSON.parseObject(chunkFile, ChunkFile.class);
        return chunkFileService.uploadChunk(file, chunk);
    }

    /**
     * 接收分片文件上传请求
     *
     * @param file      上传的文件
     * @param chunkFile 文件上传信息
     * @return 上传结果
     */
    @PostMapping("backUpload/{sumHash}")
    public synchronized SaResult backUploadReturnUrl
    (@RequestParam("file") MultipartFile file,@RequestParam("chunkFile") String chunkFile,@PathVariable("sumHash") String sumHash)
            throws NoSuchAlgorithmException, IOException, ExecutionException, InterruptedException {
        ChunkFile chunk = JSON.parseObject(chunkFile, ChunkFile.class);
        return chunkFileService.backUploadChunk(file, chunk, sumHash);
    }

    /**
     * 普通文件上传接口（数据信息不存储在数据表中）
     * @param file 文件
     * @return minio地址
     */
    @PostMapping("commentUpload")
    public SaResult commentUploadReturnUrl(MultipartFile file) {
        long size = file.getSize();
        log.info("size:" + size);
        log.info("size:" + size);
        if (size > 20 *(1024.0 * 1024.0)) {
            return SaResult.error("文件大小超过20M");
        }
        return minioService.uploadFile(file);
    }

    /**
     * 获取合并文件的总文件ID
     * 请求方式：POST
     * 请求路径：/mergeId
     *
     * @param file 合并文件对象
     * @return 总文件ID的结果对象
     */
    @PostMapping("mergeId")
    public SaResult getMergeFileId(@RequestBody MergeFile file) {
        System.out.println("file:" + file);
        return mergerFileService.getSumFileId(file);
    }

    /**
     * 检查文件完整性
     * POST请求方法
     * 参数：
     * file: MergeFile对象，待检查的文件
     * 返回值：
     * SaResult对象，文件检查结果
     */
    @PostMapping("checkFile")
    public SaResult checkFile(@RequestBody MergeFile file) {
        return mergerFileService.checkFileIntegrity(file);
    }

    @PostMapping("download/{fileId}")
    public void downloadFileByFileId(@PathVariable("fileId") String fileId, HttpServletResponse response)
            throws Exception {
        log.info("文件开始下载 .....");
        if (Objects.isNull(fileId)) {
            PrintWriter writer = response.getWriter();
            writer.println(SaResult.error("文件ID不能为空"));
            return;
        }
        mergerFileService.downloadFileByFileId(fileId, response);
        log.info("下载完成 .....");
    }

}
